unit uLib;

interface

uses
  SysUtils, Classes, Grids,Forms;

type
  TStringDynArray = array of string;

function Explode(const Separator, S: string; Limit: Integer = 0)
  : TStringDynArray;

procedure RemoveDuplicates(const stringList: TStringList);
procedure AutoSizeAllHeader(sg: TStringGrid; isLHS: Boolean = False);
procedure DeleteRow(myGrid: TStringGrid; ARow: Integer);
function IsInteger(S: String): Boolean;
function IsFloat(S: String): Boolean;

implementation

procedure DeleteRow(myGrid: TStringGrid; ARow: Integer);
var
  i: Integer;
begin
  with myGrid do
  begin
    for i := ARow to RowCount - 2 do
      Rows[i].Assign(Rows[i + 1]);
    RowCount := RowCount - 1;
    Application.ProcessMessages;
  end;
end;

procedure AutoSizeAllHeader(sg: TStringGrid; isLHS: Boolean = False);
  procedure AutoSizeCol(Grid: TStringGrid; Column: integer);
  var
    i, W, WMax: integer;
  begin
    WMax := 0;
    for i := 0 to (Grid.RowCount - 1) do
    begin
      W := Grid.Canvas.TextWidth(Grid.Cells[Column, i]);
      if W > WMax then
        WMax := W;
    end;
    Grid.ColWidths[Column] := WMax + 10;
  end;

var
  i: integer;
begin
  if isLHS then
    for i := 1 to Sg.ColCount - 1 do
      AutoSizeCol(Sg, i)
  else
    for i := 2 to Sg.ColCount - 1 do
      AutoSizeCol(Sg, i);
end;

// remove duplicate strings from the string list

procedure RemoveDuplicates(const stringList: TStringList);
var
  buffer: TStringList;
  cnt: Integer;
begin
  stringList.Sort;
  buffer := TStringList.Create;
  try
    buffer.Sorted := True;
    buffer.Duplicates := dupIgnore;
    buffer.BeginUpdate;
    for cnt := 0 to stringList.Count - 1 do
      buffer.Add(stringList[cnt]);
    buffer.EndUpdate;
    stringList.Assign(buffer);
  finally
    FreeandNil(buffer);
  end;

  { Examples
    var
    sl : TStringList;
    cnt : integer;
    begin
    Randomize;
    sl := TStringList.Create;
    try
    for cnt := 1 to 1000 do
    sl.Add(IntToStr(Random(2000))) ;

    ShowMessage('With duplicates: ' + #13#10 + IntToStr(sl.Count)) ;

    RemoveDuplicates(sl) ;

    ShowMessage('Without duplicates: ' + #13#10 + IntToStr(sl.Count)) ;
    finally
    sl.Free;
    end;
    end; }
end;

function Explode(const Separator, S: string; Limit: Integer = 0)
  : TStringDynArray;
var
  SepLen: Integer;
  F, P: PChar;
  ALen, Index: Integer;
begin
  SetLength(Result, 0);
  if (S = '') or (Limit < 0) then
    Exit;
  if Separator = '' then
  begin
    SetLength(Result, 1);
    Result[0] := S;
    Exit;
  end;
  SepLen := Length(Separator);
  ALen := Limit;
  SetLength(Result, ALen);

  Index := 0;
  P := PChar(S);
  while P^ <> #0 do
  begin
    F := P;
    P := StrPos(P, PChar(Separator));
    if (P = nil) or ((Limit > 0) and (Index = Limit - 1)) then
      P := StrEnd(F);
    if Index >= ALen then
    begin
      Inc(ALen, 5);
      SetLength(Result, ALen);
    end;
    SetString(Result[Index], F, P - F);
    Inc(Index);
    if P^ <> #0 then
      Inc(P, SepLen);
  end;
  if Index < ALen then
    SetLength(Result, Index);
end;

function IsInteger(S: String): Boolean;
begin
  try
    Result := True;
    StrToInt(S);
  except on E: EConvertError do
    Result := False;
  end;
end;

function IsFloat(S: String): Boolean;
begin
  try
    Result := True;
    StrToFloat(S);
  except on E: EConvertError do
    Result := False;
  end;
end;


end.

